package com.smart.sso.server.switchdb;

import java.sql.DriverManager;
import java.util.Map;
import java.util.Set;

import javax.sql.DataSource;

import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.util.StringUtils;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.stat.DruidDataSourceStatManager;

public class DynamicDataSource extends AbstractRoutingDataSource {
	private boolean debug = false;
	Logger log = LoggerFactory.getLogger(this.getClass());
	private Map<Object, Object> dynamicTargetDataSources;
	private Object dynamicDefaultTargetDataSource; 
	@Override
	protected Object determineCurrentLookupKey() {
		String datasource = DBContextHolder.getDataSource();
		if (debug) {
			if (StringUtils.isEmpty(datasource) || datasource.equals("MASTER")) {
				log.info("---当前数据源：默认数据源---");
			} else {
				log.info("---当前数据源：" + datasource + "---");
			}
		}
		return datasource;
	}

	@Override
	public void setTargetDataSources(Map<Object, Object> targetDataSources) {
		super.setTargetDataSources(targetDataSources);
		this.dynamicTargetDataSources = targetDataSources;
	} 
	
	// 创建数据源
	public boolean createDataSource(String key, String driveClass, String url, String username, String password) {
		try {
			try { // 排除连接不上的错误
				Class.forName(driveClass);
				DriverManager.getConnection(url, username, password);// 相当于连接数据库
			} catch (Exception e) {
				return false;
			}
			@SuppressWarnings("resource")
			DruidDataSource druidDataSource = new DruidDataSource();
			druidDataSource.setName(key);
			druidDataSource.setDriverClassName(driveClass);
			druidDataSource.setUrl(url);
			druidDataSource.setUsername(username);
			druidDataSource.setPassword(password);
			druidDataSource.setMaxWait(60000);
			druidDataSource.setFilters("stat");
			DataSource createDataSource = (DataSource) druidDataSource;
			druidDataSource.init();
			
			Map<Object, Object> dynamicTargetDataSources2 = this.dynamicTargetDataSources;
			dynamicTargetDataSources2.put(key, createDataSource);// 加入map
			setTargetDataSources(dynamicTargetDataSources2);// 将map赋值给父类的TargetDataSources
			super.afterPropertiesSet();// 将TargetDataSources中的连接信息放入resolvedDataSources管理
			return true;
		} catch (Exception e) {
			log.error(e + "");
			return false;
		}
	} 
	
	// 删除数据源
	public boolean delDatasources(String datasourceid) {
		Map<Object, Object> dynamicTargetDataSources2 = this.dynamicTargetDataSources;
		if (dynamicTargetDataSources2.containsKey(datasourceid)) {
			Set<DruidDataSource> druidDataSourceInstances = DruidDataSourceStatManager.getDruidDataSourceInstances();
			for (DruidDataSource l : druidDataSourceInstances) {
				if (datasourceid.equals(l.getName())) {
					System.out.println(l);
					dynamicTargetDataSources2.remove(datasourceid);
					DruidDataSourceStatManager.removeDataSource(l);
					setTargetDataSources(dynamicTargetDataSources2);// 将map赋值给父类的TargetDataSources
					super.afterPropertiesSet();// 将TargetDataSources中的连接信息放入resolvedDataSources管理
					return true;
				}
			}
			return false;
		} else {
			return false;
		}
	}
	
	public void cleanDatasources() {
		dynamicTargetDataSources.clear();
		dynamicTargetDataSources.put("MASTER", dynamicDefaultTargetDataSource);
	}

	// 测试数据源连接是否有效
	public boolean testDatasource(String key, String driveClass, String url, String username, String password) {
		try {
			Class.forName(driveClass);
			DriverManager.getConnection(url, username, password);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * Specify the default target DataSource, if any.
	 * <p>
	 * The mapped value can either be a corresponding
	 * {@link javax.sql.DataSource} instance or a data source name String (to be
	 * resolved via a {@link #setDataSourceLookup DataSourceLookup}).
	 * <p>
	 * This DataSource will be used as target if none of the keyed
	 * {@link #setTargetDataSources targetDataSources} match the
	 * {@link #determineCurrentLookupKey()} current lookup key.
	 */
	public void setDefaultTargetDataSource(Object defaultTargetDataSource) {
		super.setDefaultTargetDataSource(defaultTargetDataSource);
		this.dynamicDefaultTargetDataSource = defaultTargetDataSource;
	}

	/**
	 * @param debug
	 *            the debug to set
	 */
	public void setDebug(boolean debug) {
		this.debug = debug;
	}

	/**
	 * @return the debug
	 */
	public boolean isDebug() {
		return debug;
	}

	/**
	 * @return the dynamicTargetDataSources
	 */
	public Map<Object, Object> getDynamicTargetDataSources() {
		return dynamicTargetDataSources;
	}

	/**
	 * @param dynamicTargetDataSources
	 *            the dynamicTargetDataSources to set
	 */
	public void setDynamicTargetDataSources(Map<Object, Object> dynamicTargetDataSources) {
		this.dynamicTargetDataSources = dynamicTargetDataSources;
	}

}